package solutions.ferpa.ztest.rest.action;

import br.com.telescope.adsrt.lib.BaseRuntime;
import solutions.ferpa.ztest.rest.RestService;
import solutions.ferpa.ztest.rest.model.AssayInstrument;
import solutions.ferpa.ztest.rest.model.res.AssayInstrumentSearchRQ;
import solutions.ferpa.ztest.rest.model.res.AssayInstrumentSearchRS;

import java.sql.ResultSet;
import java.util.ArrayList;

public class AssayInstrumentSearch extends RestService<AssayInstrumentSearchRQ, AssayInstrumentSearchRS> {

    private static final String WHERE_CLAUSE = " where ";
    private static final String AND_CLAUSE = " and ";

    public AssayInstrumentSearch(BaseRuntime ctx) {
        super(ctx);
    }

    @Override
    public AssayInstrumentSearchRS call() throws Exception {
        AssayInstrumentSearchRQ rq = bindRequest(AssayInstrumentSearchRQ.class);
        AssayInstrumentSearchRS rs = new AssayInstrumentSearchRS();
        StringBuffer sql = new StringBuffer();
        String clause = WHERE_CLAUSE;
        sql
                .append("select iens.id, iens.nome, iens.ativo, tien.e_componente")
                .append("  from instrumento_ensaio iens")
                .append("  join tipo_instrumento_ensaio tien on (tien.id = iens.tipo_instrumento_ensaio_id)")
                .append("  left join modelo_ensaio_intrumento mein on (mein.instrumento_ensaio_id = iens.id)")
                .append("  left join modelo_hidrometro mhid on (mhid.id = mein.modelo_hidrometro_id)")
                .append("  left join operador_instrumento oins on (oins.instrumento_ensaio_id = iens.id)")
                .append("  left join pessoa pess on (pess.id = oins.operador_instrumento_id)");


        if (rq.getModelCode() != null && ! rq.getModelCode().isEmpty()) {
            sql
                    .append(clause)
                    .append("mhid.codigo ilike '")
                    .append(rq.getModelCode())
                    .append('\'');

            clause = AND_CLAUSE;
        }

        if (rq.getUserId() != null) {
            sql
                    .append(clause)
                    .append("pess.usuario_associado_id = ")
                    .append(rq.getUserId().toString());
            clause = AND_CLAUSE;
        }

        if (rq.getActive() != null) {
            sql
                    .append(clause)
                    .append("iens.ativo = \'")
                    .append(rq.getActive().booleanValue() ? 'S' : 'N')
                    .append('\'');
            clause = AND_CLAUSE;
        }

        if (rq.getComponent() != null) {
            sql
                    .append(clause)
                    .append("tien.e_componente = \'")
                    .append(rq.getActive().booleanValue() ? 'S' : 'N')
                    .append('\'');
            clause = AND_CLAUSE;
        }

        if (rq.getFlow() != null) {
            sql
                    .append(clause)
                    .append("(coalesce(iens.intervalo_valor_inicial, 0) = 0")
                    .append(String.format("or iens.intervalo_valor_inicial <= %d)", rq.getFlow().doubleValue()))
                    .append("and (coalesce(iens.intervalo_valor_final, 0) = 0")
                    .append(String.format("or iens.intervalo_valor_final >= %d)", rq.getFlow().doubleValue()));
        }

        ResultSet res = null;

        try {
            executeQuery(sql.toString());
            while (res.next()) {
                AssayInstrument instrument = new AssayInstrument();
                instrument.setId(res.getInt(1));
                instrument.setName(res.getString(2));
                instrument.setActive(res.getString(3).equals("S"));
                instrument.setComponent(res.getString(4).equals("S"));
                if (rs.getResource() == null) rs.setResource(new ArrayList<AssayInstrument>());
                rs.getResource().add(instrument);
            }
        } catch (Exception e) {
            throw e;
        } finally {
            if (res != null) res.close();
        }

        return rs;
    }
}